import java.util.ArrayList;
/**
 * Created by yuchen on 16/5/10.
 */
public class dotSets {

    private int length;
    private int width;
    private int height;
    ArrayList<dataSet> data;

    public dotSets(int length, int width, int height) {
        this.length = length + 1;
        this.width = width;
        this.height = height;
        this.data = new ArrayList<>(length + 1);

    }

    public void init(){
        int k;
        for (k = 0; k < this.length; k++) {
            this.data.add(k,new dataSet(width, height));
        }
    }

    public void flush() {
        int k;
        for (k = 0; k < this.length; k++) {
            this.data.get(k).flush();
        }
    }


    public void filter(){
        int len = this.length;
        int i, pos;
        pos = len - 1;
        for (i = len - 1; i > 0; i--) {
            dataSet dataset = this.data.get(i);
            boolean condition = false;
            condition = condition || dataset.getLength() < 10;   //点少于10个
            condition = condition || dataset.getAreaWidth() > (width * 2 / 3);
            condition = condition || dataset.getAreaWidth() < 3;
            condition = condition || dataset.getAreaHeight() < 3;
            condition = condition || dataset.isnoise();
            condition = condition || (dataset.getLength() < 30 && (int)dataset.getArea().get(3) < (this.height) / 2);
            if (condition) {
                swap(i,pos);
                pos--;
            }
        }
        if (pos + 1 < len) {
            this.splice(this.data, pos + 1, len - pos - 1);
            this.length = this.data.size();
        }
    }

    public void filterSobelSimple(){
        int len = this.length;
        int i, pos;
        pos = len - 1;
        for (i = len - 1; i > 0; i--) {
            dataSet dataset = this.data.get(i);
            boolean condition = false;
            condition = condition || dataset.getLength() < 100;   //点少于100个
            condition = condition || dataset.getAreaHeight() <(this.height/2);
            condition = condition || dataset.getAreaWidth() <(this.width/3);
            if (condition) {
                this.swap(i, pos);
                pos--;
            }
        }
        if (pos + 1 < len) {
            int removeCount = len-pos-1;
            for(int f = 0; i < removeCount ; i++)
            {
                this.data.remove(pos + 1);
            }
            this.length = this.data.size();
        }
    }

    public int[] fillSobel(){
        int[] cluster = new int[this.height * this.width];
        int i, j, k, x, y;
        k = cluster.length;
        for (i = 0; i < k; i++) {
            cluster[i] = 0;
        }
        dataSet dataset = this.data.get(1);
        int datalen = this.data.get(1).data.size();
        ArrayList data = this.data.get(1).data;
        for(j=0;j<datalen;j++){
            x = ((int[])data.get(j))[0];
            y = ((int[])data.get(j))[1];
            cluster[x + y * this.width] = 1;
        }
        int minW=(int)dataset.getArea().get(0), maxW=(int)dataset.getArea().get(1), minH=(int)dataset.getArea().get(2), maxH=(int)dataset.getArea().get(3);
        int startW,endW,ids;
        for(i=minH;i<=maxH;i++){
            startW = maxW;endW =minW;
            for(j=minW;j<=maxW;j++){
                ids = j+i*this.width;
                if(cluster[ids]==1 ){
                    startW = j;
                    break;
                }//if cluster
            }// for j
            for(j=maxW;j>=minW;j--){
                ids = j+i*this.width;
                if(cluster[ids]==1 ){
                    endW = j;
                    break;
                }//if cluster
            }// for j
            for(j=startW;j<=endW;j++){
                ids = j+i*this.width;
                cluster[ids]=1;
            }
        }//for i
        return cluster;
    }

    public int[] getMask(int[] cluster){
        int[] mask;
        if(cluster.length > 0){
            mask = cluster;
        }else{
            mask = this.fillSobel();
        }
        int i;
        for(i=0;i<mask.length;i++){
            if(mask[i]==1){
                mask[i]=255;
            }
        }
        return mask;
    }

    public void SelectAreaSobel(){
        int len = this.length;
        if(len <= 2){
            return;
        }
        int i, count;
        int maxCount = -1, maxIndex = 0;
        int y = height/2;
        int starX = width/3;
        int endX = width*2/3;
        for(i=1;i<len;i++){
            count = this.data.get(i).counthorizontal(y,starX,endX);
            if(count > maxCount){
                maxCount = count;
                maxIndex = i;
            }
        }
        this.swap( 1 , maxIndex );
        this.splice(this.data,2,len-2);
        this.length = this.data.size();
    }



    public void swap(int n, int pos) {
        dataSet a = this.data.get(n);
        dataSet b = this.data.get(pos);
        if (n != pos)  {
            this.data.set(n,b);
            this.data.set(pos,a);
        }
    }

    public void splice(ArrayList lists,int start,int count)
    {
        for(int i = 0; i < count; i++){
            lists.remove(start);
        }
    }

    public int getLength(){
        return this.length;
    }

}

